package com.xusheng.cli.controller.open;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xusheng.cli.common.base.Result;
import com.xusheng.cli.common.constant.Constant;
import com.xusheng.cli.common.validation.Save;
import com.xusheng.cli.entity.downloadStatisticsModule.DownloadStatistics;
import com.xusheng.cli.entity.frontUserModule.FrontUser;
import com.xusheng.cli.entity.frontUserModule.VipConfig;
import com.xusheng.cli.entity.proxyHostModule.ProxyHost;
import com.xusheng.cli.entity.vipLevelModule.VipLevel;
import com.xusheng.cli.req.LoginReq;
import com.xusheng.cli.service.*;
import com.xusheng.cli.tools.InviteCodeUtils;
import com.xusheng.cli.tools.IpUtil;
import com.xusheng.cli.tools.SMSVerificationCode;
import com.xusheng.cli.tools.StpPlayerUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;

/**
 * app登陆注册接口
 *
 * @author lyh
 * @since 2023-04-27 15:11
 */
@RestController
@Slf4j
@RequestMapping("/open/v1/app")
public class AppLoginController {

    @Resource
    private FrontUserService frontUserService;
    @Resource
    private VipConfigService vipConfigService;
    @Resource
    private VipLevelService vipLevelService;
    @Resource
    private RedisTemplate<String, String> redisTemplate;

    @Resource
    private ProxyHostService proxyHostService;

    @Resource
    private ProxyHostTwoService proxyHostTwoService;

    @Resource
    private ProxyHostThreeService proxyHostThreeService;

    @Resource
    private DownloadStatisticsService downloadStatisticsService;

    /**
     * 注册
     *
     * @param user 用户信息
     * @return 返回结果
     */
    @PostMapping("/register")
    public Result<Dict> register(@Validated(Save.class) @RequestBody FrontUser user) {
        log.info("-----------------------代理id{}", user.getProxyId());
        String key = SMSVerificationCode.M_REGIST_KEY + user.getAccount();
        String c = redisTemplate.opsForValue().get(key);
        log.info("key={}, redis-code = {}, user-code={}", key, c, user.getSmsCode());
        if (StrUtil.isBlank(c) || !c.equals(user.getSmsCode())) {
            return Result.error("短信验证码不正确");
        }
        redisTemplate.delete(key);
        long count = frontUserService.lambdaQuery()
                .eq(FrontUser::getAccount, user.getAccount())
                .count();
        if (count > 0) {
            return Result.error("账号名已存在");
        }

        user.setPassword(DigestUtil.bcrypt(user.getPassword()));
        user.setLastLoginTime(LocalDateTime.now());
        user.setInviteCode(getCode());
        user.setInviteNumber(0);
        user.setGold(0);
        user.setWatchCount(0);
        user.setWatchCountShort(0);
        // 获取代理id
        String serverName = user.getHost();
        Long proxyId = null;
        if (StrUtil.isNotBlank(serverName)) {
            Long proxyThree = proxyHostThreeService.selectProxyByThree(serverName);
            if (proxyThree == null) {
                Long proxyTwo = proxyHostTwoService.selectProxyByTwo(serverName);
                if (proxyTwo == null) {
                    ProxyHost proxyHost = proxyHostService.lambdaQuery().eq(ProxyHost::getHost, serverName).one();
                    if (proxyHost != null) {
                        proxyId = proxyHost.getProxyId();
                    }
                } else {
                    proxyId = proxyTwo;
                }
            } else {
                proxyId = proxyThree;
            }
        }
        user.setProxyId(proxyId);
        // 结算推广奖励
        getPromotionLevel(user);
        boolean success = frontUserService.save(user);
        if (!success) {
            return Result.error("注册失败");
        }
        // 生成注册记录
        registerStatistics(IpUtil.getClientIp());
        // 邀请人码
        if (StrUtil.isNotBlank(user.getInviterCode())) {
            FrontUser inviter = frontUserService.getOne(new LambdaQueryWrapper<FrontUser>().eq(FrontUser::getInviteCode, user.getInviterCode()));
            if (inviter != null) {
                inviter.setInviteNumber(inviter.getInviteNumber() + 1);
                // 结算推广奖励
                getPromotionLevel(inviter);
                frontUserService.updateById(inviter);
            }
        }
        StpPlayerUtil.login(user.getId(), Constant.APP);
        StpPlayerUtil.getSession().set(Constant.PLAYER, user);
        Dict dict = Dict.create();
        dict.set("user", user);
        dict.set("token", StpPlayerUtil.getTokenValue());
        return Result.success(dict);
    }

    private void getPromotionLevel(@RequestBody @Validated(Save.class) FrontUser user) {
        List<VipLevel> vipLevelList = vipLevelService.list(new QueryWrapper<>(new VipLevel()).orderByAsc("id"));
        for (int i = 0; i < vipLevelList.size(); i++) {
            if (user.getInviteNumber() >= vipLevelList.get(i).getPromotionCount()) {
                user.setPromotionLevel(vipLevelList.get(i).getId());
                user.setWatchCount(vipLevelList.get(i).getWatchCount());
                user.setWatchCountShort(vipLevelList.get(i).getWatchCountShort());
                user.setVipLevel(vipLevelList.get(i));
            }
        }
    }

    /**
     * 获取邀请码
     *
     * @return
     */
    public String getCode() {
        String code = InviteCodeUtils.generateCode();
        FrontUser one = frontUserService.getOne(new LambdaQueryWrapper<FrontUser>().eq(FrontUser::getInviteCode, code));
        if (one != null) {
            // 有重复重新生成
            return getCode();
        } else {
            return code;
        }
    }

    /**
     * 登陆
     *
     * @param req 登陆信息
     * @return 返回结果
     */
    @PostMapping("/login")
    public Result<Dict> login(@Validated @RequestBody LoginReq req) {
        LambdaQueryWrapper<FrontUser> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(FrontUser::getAccount, req.getAccount());
        FrontUser user = frontUserService.getOne(wrapper);
        if (user == null) {
            return Result.error("账户或密码错误");
        }
        if (StrUtil.isNotBlank(req.getPassword())) {
            String password = user.getPassword();
            Assert.notBlank(password, "密码不能为空");
            boolean b = DigestUtil.bcryptCheck(req.getPassword(), password);
            if (!b) {
                return Result.error("账号或密码错误");
            }
        }
        // 短信登录
        if (StrUtil.isNotBlank(req.getCode())) {
            String key = SMSVerificationCode.M_REGIST_KEY + req.getAccount();
            String c = redisTemplate.opsForValue().get(key);
            log.info("key={}, redis-code = {}, user-code={}", key, c, req.getCode());
            if (StrUtil.isBlank(c) || !c.equals(req.getCode())) {
                return Result.error("短信验证码不正确");
            }
            redisTemplate.delete(key);
        }
        user.setVipName("默认会员");
        StpPlayerUtil.login(user.getId(), Constant.APP);
        StpPlayerUtil.getSession().set(Constant.PLAYER, user);
        if (user.getVipId() != null && user.getVipExpires() != null) {
            LocalDateTime expire = user.getVipExpires();
            LocalDateTime now = LocalDateTime.now();
            if (now.isBefore(expire)) {
                VipConfig vip = vipConfigService.getById(user.getVipId());
                user.setVipName(vip.getName());
            }
        }
        frontUserService.update(Wrappers.<FrontUser>lambdaUpdate()
                .set(FrontUser::getLastLoginTime, LocalDateTime.now())
                .eq(FrontUser::getId, user.getId()));
        user.setVipLevel(vipLevelService.getById(user.getPromotionLevel()));
        Dict dict = Dict.create();
        dict.set("user", user);
        dict.set("token", StpPlayerUtil.getTokenValue());
        return Result.success(dict);
    }

    /**
     * 生成注册统计
     *
     * @param ip
     */
    public void registerStatistics(String ip) {
        log.info("当前用户IP为{}", ip);
        DownloadStatistics data = new DownloadStatistics();
        data.setIp(ip);
        data.setType(1);
        data.setAddr(IpUtil.getAddress(ip));
        log.info("正在生成注册记录");
        downloadStatisticsService.save(data);
    }

    public static void main(String[] args) {

        System.out.println(IpUtil.getAddress("221.200.99.56"));
    }
}
